package de.preamp.clients.java.lib.ui;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;

import org.json.JSONException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

import de.preamp.clients.java.data.AbstractDBItem;
import de.preamp.clients.java.data.Album;
import de.preamp.clients.java.data.Artist;
import de.preamp.clients.java.data.Track;
import de.preamp.clients.java.lib.AbstractLibrary;
import de.preamp.clients.java.lib.ArtistLibrary;
import de.preamp.clients.java.lib.RootLibrary;
import de.preamp.clients.java.utils.ImageLoader;
import de.preamp.clients.java.utils.ui.PreferencesUI;

/**
 * @author André Stannek
 * @version 2011-06-11
 */
public class LibraryUIFancy extends AbstractLibraryUI
{
    /**
     * Generated UID.
     */
    private static final long serialVersionUID = -8470783043912610233L;

    /**
     * 
     */
    private JPanel header;

    /**
     * 
     */
    private StatusBar statusBar;

    /**
     * 
     */
    private JComponent dbContentPane;

    /**
     * 
     */
    private JScrollPane dbPane;

    /**
     * 
     */
    private JButton backButton, searchButton;

    /**
     * 
     */
    private JTextField searchText;

    /**
     * 
     */
    private final LibraryBean bean;

    /**
     * 
     */
    public LibraryUIFancy()
    {
	final ApplicationContext context =
		new FileSystemXmlApplicationContext(
			"src/main/resources/META-INF/applicationContext.xml");
	bean = (LibraryBean) context.getBean("libraryBean");
	initUI();
    }

    /**
     * initiates the UI components.
     */
    private void initUI()
    {
	header = new JPanel();
	statusBar = new StatusBar();
	dbContentPane = new JPanel();
	dbPane = new JScrollPane();

	this.setLayout(new BorderLayout());

	initFooter();
	initHeader();
	setContent();
    }

    /**
     * 
     */
    private void initHeader()
    {
	header.setLayout(new BorderLayout());
	this.add(header, BorderLayout.NORTH);
	backButton = new JButton();
	backButton.setIcon(new ImageIcon(ImageLoader
		.getImageURL("go-previous.png")));
	backButton.addActionListener(new ActionListener()
	{
	    @Override
	    public void actionPerformed(final ActionEvent e)
	    {
		setContent();
	    }
	});
	backButton.setSize(32, 32);
	backButton.setEnabled(false);
	header.add(backButton, BorderLayout.WEST);
	final JPanel filter = new JPanel(new BorderLayout());
	searchText = new JTextField();
	searchText.addKeyListener(new KeyAdapter()
	{
	    @Override
	    public void keyPressed(final KeyEvent event)
	    {
		if (event.getKeyCode() == KeyEvent.VK_ENTER)
		{
		    setContent(searchText.getText());
		}
	    }
	});
	searchButton =
		new JButton(new ImageIcon(
			ImageLoader.getImageURL("system-search.png")));
	searchButton.addActionListener(new ActionListener()
	{
	    @Override
	    public void actionPerformed(final ActionEvent e)
	    {
		setContent(searchText.getText());
	    }
	});
	filter.add(searchButton, BorderLayout.EAST);
	filter.add(searchText, BorderLayout.CENTER);
	header.add(filter, BorderLayout.CENTER);
    }

    /**
     * 
     */
    private void initFooter()
    {
	this.add(statusBar, BorderLayout.SOUTH);

	statusBar.setStatusMessage("test");
    }

    /**
     * Sets the root content (all artists).
     */
    private void setContent()
    {
	setContent(bean.getRootLibrary());

	backButton.setEnabled(false);
    }

    /**
     * @param lib
     *            the library to set the content for
     */
    private void setContent(final AbstractLibrary lib)
    {
	this.remove(dbPane);

	final JList list = new JList(lib);
	list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	list.setDragEnabled(true);
	list.setCellRenderer(new DBItemCellRenderer());
	list.setTransferHandler(new LibraryItemTransferHandler());

	if (lib instanceof RootLibrary)
	{
	    list.setFixedCellHeight(100);
	    list.setFixedCellWidth(300);
	    list.addMouseListener(new MouseAdapter()
	    {
		@Override
		public void mouseClicked(final MouseEvent event)
		{
		    if (event.getButton() == MouseEvent.BUTTON1)
		    {
			setContent((Artist) list.getSelectedValue());
		    }
		    else if (event.getButton() == MouseEvent.BUTTON3)
		    {
			final int index =
				list.locationToIndex(event.getPoint());
			final Object selected =
				list.getModel().getElementAt(index);
			if (selected instanceof AbstractDBItem)
			{
			    final ItemContextMenueUI menu =
				    new ItemContextMenueUI(
					    (AbstractDBItem) selected);
			    menu.show(event.getComponent(), event.getX(),
				    event.getY());
			}
		    }
		}
	    });
	}

	list.addMouseListener(new MouseAdapter()
	{

	    @Override
	    public void mouseClicked(final MouseEvent e)
	    {
		final int index = list.locationToIndex(e.getPoint());
		final Object selected = list.getModel().getElementAt(index);
		if (e.getButton() == MouseEvent.BUTTON1
			&& e.getClickCount() == 2)
		{
		    if (selected instanceof Track)
		    {
			bean.getPlaylistManager().getSelectedPlaylist()
				.add((Track) selected);
		    }
		    else if (selected instanceof Album)
		    {
			for (final Track track : ((Album) selected).getTracks())
			{
			    bean.getPlaylistManager().getSelectedPlaylist()
				    .add(track);
			}
		    }
		}
		else if (e.getButton() == MouseEvent.BUTTON3)
		{
		    if (selected instanceof AbstractDBItem)
		    {
			final ItemContextMenueUI menu =
				new ItemContextMenueUI(
					(AbstractDBItem) selected);
			menu.show(e.getComponent(), e.getX(), e.getY());
		    }
		}
	    }
	});
	dbContentPane = list;

	dbPane = new JScrollPane(dbContentPane);
	this.add(dbPane, BorderLayout.CENTER);

	this.validate();
    }

    /**
     * Sets all albums for an artists as content.
     * 
     * @param artist
     *            the artist.
     */
    private void setContent(final Artist artist)
    {
	this.remove(dbPane);

	try
	{
	    setContent(new ArtistLibrary(artist));
	}
	catch (final JSONException e1)
	{
	    JOptionPane.showMessageDialog(this,
		    "Got invalid result from server. "
			    + "Try running an update on the server.",
		    "server connection error", JOptionPane.ERROR_MESSAGE);
	}
	catch (final IOException e1)
	{
	    JOptionPane.showMessageDialog(this,
		    "Connection to server unavailable",
		    "server connection error", JOptionPane.ERROR_MESSAGE);
	    new PreferencesUI(null);
	}

	backButton.setEnabled(true);
    }

    /**
     * @param search
     *            the search keyword for the content
     */
    private void setContent(final String search)
    {
	try
	{
	    setContent(bean.getSearchLibrary(search));
	}
	catch (final JSONException e1)
	{
	    JOptionPane.showMessageDialog(this,
		    "Got invalid result from server. "
			    + "Try running an update on the server.",
		    "server connection error", JOptionPane.ERROR_MESSAGE);
	}
	catch (final IOException e1)
	{
	    JOptionPane.showMessageDialog(this,
		    "Connection to server unavailable",
		    "server connection error", JOptionPane.ERROR_MESSAGE);
	    new PreferencesUI(null);
	}

	backButton.setEnabled(true);
    }
}
